import { AssetManager, SpriteFrame } from "cc";
import { js } from "cc";
import { instantiate } from "cc";
import { Prefab } from "cc";
import { resources } from "cc";
import { Asset, assetManager,Node } from "cc";



export default class loader {

    static async loadurl(url: string, type: typeof Asset = Asset): Promise<Asset> {
        return new Promise((resolve, reject) => {
            assetManager.resources.load(url, type, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        });
    }

    static loadlocalCache<T extends Asset>(path:string,bundleName?: string):T{

        let bundle = resources;
        if(bundleName){
            bundle = assetManager.getBundle(bundleName) || bundle;
        }

        return bundle.get<T>(path);

    }

    static async loadlocal<T extends Asset>(path:string,bundleName?: string): Promise<T> {

        if(bundleName){
            let bundle = await loader.getBundle(bundleName) as AssetManager.Bundle;
            if(bundle.get<T>(path)) return bundle.get<T>(path);
            return new Promise((resolve, reject) => {
                bundle.load<T>(path,(err, res: T) => {
                    //assets.addRef();
                    if (err) {
                        reject(err);
                        return
                    }
                    resolve(res);
                })
            })
        }else{
            if(resources.get<T>(path)) return resources.get<T>(path);
            return new Promise((resolve, reject) => {
                resources.load<T>(path,(err, res) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(res);
                    }
                })
            })
        }

    }
    
    static async loadPrefab(uiPrefabPath: string, bundleName?: string): Promise<Node> {
        
        bundleName = bundleName || "resources";
        let bundle = await loader.getBundle(bundleName) as AssetManager.Bundle;
        
        if(bundle.get<Prefab>(uiPrefabPath)) {
            let prefab = bundle.get<Prefab>(uiPrefabPath);
            return instantiate(prefab);
        }

        return new Promise((res, rej) => {
            bundle.load(uiPrefabPath, Prefab, (err, assets: Prefab) => {
                //assets.addRef();
                if (err) {
                    res(null);
                    return
                }
                res(instantiate(assets));
            })
        })

    }
    
    static async getBundle(bundleName) {
        let bundle = assetManager.getBundle(bundleName);
        if (bundle) {
            return bundle;
        } else {
            return await loader.loadBundle(bundleName);
        }
    }

    static async loadBundle(bundleName):Promise<AssetManager.Bundle> {
        return new Promise((res, rej) => {
            assetManager.loadBundle(bundleName, (err, bundle) => {
                if (!err) {
                    res(bundle);
                } else {
                    rej(bundle);
                }
            })
        })
    }

    static async release(bundleName,path = null){
        let bundle = assetManager.getBundle(bundleName);
        if(!bundle) return;
        if(path == null)
            bundle.releaseAll();
        else{
            let asset = bundle.get(path);
            if (asset) {
                assetManager.releaseAsset(asset);
            }
        }
    }

}


